<template>
  <div class="coupon-list">
    <div class="coupon-box">
      <template v-for="group in showCouponList" :key="group.label">
        <couponItem
          v-for="it in group.options"
          :key="it.c_id"
          :currentCoupon="currentCoupon"
          :it="it"
          :available="group.available"
          @switch="handleCouponChange"
          @use="handleUseCoupon"
        />
      </template>
    </div>
    <el-dropdown
      trigger="click"
      popper-class="coupon-popper"
      placement="top-start"
      ref="couponDropdown"
    >
      <div class="list-select-btn">
        <svg-icon icon-class="coupon-list-select-icon" :size="8" />
      </div>
      <template #dropdown>
        <div class="coupon-options">
          <div
            v-for="group in couponOptions"
            :key="group.label"
            class="coupon-group"
          >
            <div class="coupon-group-name">{{ group.label }}</div>
            <couponItem
              v-for="it in group.options"
              :key="it.c_id"
              :currentCoupon="currentCoupon"
              :it="it"
              :available="group.available"
              @switch="handleCouponChange"
              @use="handleUseCoupon"
            />
          </div>
        </div>
      </template>
    </el-dropdown>
  </div>
</template>
<script setup lang="ts">
import { defineProps, ref, watch, nextTick, defineEmits, computed, onMounted, onActivated, onUnmounted, onDeactivated, defineExpose } from "vue";
import { useRouter, useRoute } from "vue-router";
import { storeToRefs } from "pinia";
import { getUsageList } from "@/api/coupon";
import { systemAppStore } from "@/stores/system";
import { userAppStore } from "@/stores/user";
import { debounce } from "@/utils";
import { getLeftTime } from "@/utils/costum";
import couponItem from "./coupon-item.vue";
import { formatMoney } from "@/utils/costum";
import type { DropdownInstance } from 'element-plus';
import eventBus from '@/utils/mitt';
const emit = defineEmits(["update:data", "couponChange", "selectProductByCoupon", "canRefreshCouponByCoupon"]);
const route = useRoute();
const router = useRouter();
const _systemAppStore_ = systemAppStore();
const _userAppStore_ = userAppStore();
const { appInfo } = storeToRefs(_systemAppStore_);
const { hasLogin } = storeToRefs(_userAppStore_);
const props = defineProps<{price: number, data: any[]}>();
const couponDropdown = ref<DropdownInstance|null>(null);
const currentCoupon = ref({
  coupon_id: 0,
  amount: 0
});
const couponList = computed({
  get() {
    return props.data;
  },
  set(val) {
    emit("update:data", val);
  }
});
const availableCouponList = computed(() => {
  const _availableCouponList = couponList.value.filter(
    (coupon) => formatMoney(coupon.threshold) <= props.price
  );
  return _availableCouponList;
});
const disabledCouponList = computed(() => {
  const price: number = props.price || 0;
  return couponList.value.filter(
    ({ threshold }: any) => formatMoney(threshold) > price
  );
});
const showCouponList = computed<any[]>(() => {
  const availableList = availableCouponList.value
  const disabledList = disabledCouponList.value
  const list = [];
  let available = [];
  if (availableList.length) {
    const currCouponIdx = availableList.findIndex(
      (it: any) => it.c_id === currentCoupon.value.coupon_id
    );
    if (currCouponIdx >= 2) {
      available = availableList.slice(0, 1);
      available.push(
        availableList.slice(currCouponIdx, currCouponIdx + 1)[0]
      );
    } else {
      available = availableList.slice(0, 2);
    }
    list.push({
      label: "可用券",
      available: true,
      options: available
    });
  }
  if (available.length < 2 && disabledList.length) {
    list.push({
      label: "更高优惠",
      options: disabledList.slice(0, 2 - available.length)
    });
  }
  return list;
});
const couponOptions = computed<any>(() => {
  const availableList = availableCouponList.value
  const disabledList = disabledCouponList.value
  const list = [];
  if (availableList.length) {
    list.push({
      label: "可用券",
      available: true,
      options: availableList
    });
  }
  if (disabledList.length) {
    list.push({
      label: "更高优惠",
      options: disabledList
    });
  }
  return list;
});
let timer: number | null = null;
const getCouponListDb = debounce(
  () => {
    getCouponList();
  },
  1000,
  true
);
eventBus.on("updateUserCoupon", handleUpdateUserCoupon)
watch(availableCouponList, (val) => {
  handleCouponChange(val[0] || {});
});
onActivated(() => {
  getCouponListDb();
});
onMounted(() => {
  getCouponListDb();
});
onUnmounted(() => {
  timer && clearTimeout(timer);
  eventBus.off("updateUserCoupon", handleUpdateUserCoupon)
});
onDeactivated(() => {
  timer && clearTimeout(timer);
});
defineExpose({
  handleCouponChange,
  getCouponListDb,
  getCouponList
});
function toCoupon() {
  if (!availableCouponList.value.length) {
    return;
  }
  router.push({ name: "Coupon" });
}
// 切换优惠券
function handleCouponChange({ c_id = 0, amount = 0 }) {
  currentCoupon.value.coupon_id = c_id;
  currentCoupon.value.amount = amount;
  emit("couponChange", currentCoupon.value);

  couponDropdown.value?.handleClose();
}
// 切换满足优惠券套餐
function handleUseCoupon(info: any) {
  emit("selectProductByCoupon", info);

  couponDropdown.value?.handleClose();
}
function getCouponList({ coupon_id }: any = {}) {
  timer && clearTimeout(timer);
  if (!hasLogin.value) {
    couponList.value = [];
    return;
  }
  getUsageList(
    {
      p_id: appInfo.value.allPackages[0]
    },
    true
  )
    .then(({ data, res_headers }: any) => {
      let defaultSelCouponInfo = null;
      let { date: serverTime } = res_headers || {};
      const localTime = Math.round(Date.now() / 1000);
      serverTime = serverTime
        ? Math.round(new Date(serverTime).getTime() / 1000)
        : localTime;
        
      couponList.value = (data.list || [])
        .sort(({ amount: a }: { amount: number }, { amount: b }: { amount: number }) => b - a)
        .map((it: any) => {
          const { expire_at } = it;
          it.serverTime = serverTime;
          it.localTime = localTime;

          it.expireSecond = getLeftTime(expire_at, serverTime, localTime);
          it.amount_ = formatMoney(it.amount);

          if (coupon_id === it.coupon_id) {
            defaultSelCouponInfo = it;
          }
          return it;
        });
      nextTick(() => {
        startDownTime();
      });
      if (defaultSelCouponInfo) {
        // 默认定位到券
        emit("selectProductByCoupon", defaultSelCouponInfo);
      }
    })
    .catch((e) => {
      couponList.value = [];
    });
}
function startDownTime() {
  timer && clearTimeout(timer);
  if (!couponList.value.length) {
    return;
  }
  timer = setTimeout(() => {
    let expireCoupon: any = false;
    couponList.value.forEach((it: any) => {
      const { expireSecond, expire_at, serverTime, localTime } = it;
      if (expireSecond) {
        it.expireSecond = getLeftTime(expire_at, serverTime, localTime);
      }
      if (!expireSecond) {
        expireCoupon = it;
      }
    });
    timer = null;

    if (expireCoupon) {
      emit("canRefreshCouponByCoupon", expireCoupon);
    } else {
      startDownTime();
    }
  }, 1000) as unknown as number;
}
function handleUpdateUserCoupon(){
  if(["UserCenter", "Pay"].includes(route.name as string)){
    getCouponList()
  }
}
</script>
<style lang="scss" scoped>
.coupon-list {
  display: flex;
  align-items: center;
}
.coupon-box {
  flex: 1;
  display: flex;
  align-content: center;
  gap: 8px;
}
.coupon-options {
  max-height: 280px;
  overflow: auto;
  padding: 0 20px;
  .coupon-group-name {
    font-weight: bold;
    font-size: 14px;
    color: var(--el-text-color-primary);
    margin-bottom: 10px;
  }
  .coupon-item {
    margin-bottom: 10px;
  }
}

.list-select-btn {
  width: 12px;
  height: 60px;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;

  &:hover {
    background: rgba(0, 0, 0, 0.3);
  }
}
</style>
<style lang="scss">
.el-popper.coupon-popper {
  width: 364px;
  box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1);
  border-radius: 10px;
  border: 1px solid #cfcfcf;
  padding: 20px 4px;
}
</style>
